package General;
import java.util.InputMismatchException;
//import java.util.LinkedList;
import java.util.Scanner;

import javax.swing.JOptionPane;

import Card.Card;


public class GUI {
	private class ComboItem{
		int index;
		Object display;
		ComboItem(int i, Object s){
			index = i;
			display = s;
		}
		public int toInt(){
			return index;
		}
		public Integer toInteger(){
			return new Integer(index);
		}
		@Override
		public String toString(){
			return display.toString();
		}
	}
	public void programIntro()
	{
        //Precondition: none
        //Postcondition:Displays program introduction
            Game7.displayText("The Drums of war are sounding throughout the land.");
            Game7.displayText("Your rivals march against you and your allies are all but vanquished");
            Game7.displayText("Will you be but a mere footnote in the dusty tome that is time?");
            Game7.displayText("Or will you rise up to vanquish your FOES?!");
            Game7.displayText("This is AGE OF MYTHOLOGY!\n");  
    }//end method programIntro

   public int getMenuOption(Player player)
    {
    //Precondition: none;
    //Postcondition: Display the the menu
    //                 Prompts user and returns the menu options
        int menuOption;
        System.out.println("              Age Of Mythology              ");
        System.out.println("What will you do? WHAT WILL YOU DOOOOOO "+player.getName()+"?!?!");
        System.out.println("1. Draw Action cards");
        System.out.println("2. Do something else");
        System.out.println("3. Do a third thing, unlike the other things.");
        System.out.println("4. Exit the BLOODY PROGRAM");
        menuOption = getValidNonNegInt("Enter a number: ");
        return menuOption;
    }//end method getMenuOption
    
    public void prompt(String[] options, Player player){
        Game7.displayText("              Age Of Mythology              ");
        for(int i = 0; i<options.length;i++){
        	Game7.displayText(i+". "+options[i]);        	
        }
    }
    
    public int getValidNonNegInt(String prompt)
    {
    //Precondition: Prompt is the prompt for the integer
    //Postcondition: Prompt for and return a non-negative integer
        Scanner input = new Scanner(System.in);
        int userInput=0;
        boolean failed = true;
        System.out.print(prompt);
        do {
            try{
                userInput=input.nextInt();//This method can throw an exception
                if (userInput>=0)
                    failed=false;
                else
                    System.out.print("Invalid non-negative integer. Please reenter");
            }//end try block
            catch (InputMismatchException ex){
                System.out.print("Invalid non-negative integer. Please reenter");
            }//end catch block
            input.nextLine();
        }while (failed);
            return userInput;
     }//end method getValidNonNegInt
    public int getBoundedInt(String prompt, int start, int end)
    {
    //Precondition: Prompt is the prompt for the integer
    //Postcondition: Prompt for and return a valid integer
        int userInput=0;
        boolean failed = true;
        String s = JOptionPane.showInputDialog(prompt);
        do {
            try{
                userInput= Integer.parseInt(s);//This method can throw an exception
                if (userInput>=start && userInput <= end)
                    failed=false;
                else
                	JOptionPane.showMessageDialog(null, "Invalid input. Please reenter");
            }//end try block
            catch (NumberFormatException ex){
            	JOptionPane.showMessageDialog(null, "Invalid input. Please reenter");
            }//end catch block
            if (failed) s = JOptionPane.showInputDialog(prompt);
        }while (failed);
        return userInput;
     }//end method getBoundedInt
    
    public int assignVictory(Player player){
/*    	int i = 0;
    	String[] menuOptions = new String[VictoryCards.values().length];
    	for(VictoryCards cards: VictoryCards.values()){
    		menuOptions[i] = cards.toString()+": "
    		+Bank.singletonBank.getVictory(cards);
//    		prompt(menuOptions, player);
//    		Game7.DisplayText(menuOptions[i]);
    		i++;
    	}*/
    	int answer = getBoundedInt(player.getName()+". Please choose a Victory Card to place a cube" +
    			"\n0:Largest Army, 1:Most Buildings; 2:Last Battle Victory, 3:Wonder Building",0,3);
//    	prompt(menuOptions, player);
    	return answer;
    }
    public int recruitCards(int culture)
    {
    	String[] menuOptions = {Unit.getUnit(culture)[0].name,Unit.getUnit(culture)[1].name,Unit.getUnit(culture)[2].name,Unit.getUnit(culture)[3].name,Unit.getUnit(culture)[4].name, Unit.getUnit(culture)[5].name, Unit.getUnit(culture)[6].name, Unit.getUnit(culture)[7].name, Unit.getUnit(culture)[8].name};
    	ComboItem[] combo= new ComboItem[menuOptions.length];
    	for(int i = 0; i<combo.length; i++){
    		combo[i] = new ComboItem(i,menuOptions[i]);
    	}
    	ComboItem out=null;
    	while(out == null){
    		out = (ComboItem) JOptionPane.showInputDialog(null, "Pick a unit", "Unit picker", JOptionPane.YES_OPTION, null, combo, combo[0]);
    		System.out.print(out);
    		System.out.println(out.toInt());
    	}
    	return out.toInt();
    }
    public int drawCard(Player player){
    	//display current hand
    	displayHand(player);
    	//display options
    	
    	String[] menuOptions = {"Random","Age","Attack","Build","Explore", "Gather", "Recruit", "Trade", "Pass"};
    	ComboItem[] combo= new ComboItem[menuOptions.length];
    	for(int i = 0; i<combo.length; i++){
    		combo[i] = new ComboItem(i,menuOptions[i]);
    	}
    	ComboItem out=null;
    	while(out == null){
    		out = (ComboItem) JOptionPane.showInputDialog(null, "Draw a card", "card drawer", JOptionPane.YES_OPTION, null, combo, combo[0]);
    		System.out.print(out);
    		System.out.println(out.toInt());
    	}
    	return out.toInt();
//    	return getBoundedInt("Please choose a type of card to draw" +
//    			"\nPlease remember that you may not draw a permanent action card after you draw a random card (0,8)"
//    			+"\n0:Random, 1:Age, 2:Attack, 3:Build, 4:Explore, 5:Gather, 6:Recruit, 7:Trade, 8:Pass",
//    			0,menuOptions.length-1);
    }
    public int drawRandom(Player player){
    	displayHand(player);
    	String[] menuOptions = {"Draw Random", "Pass"};
    	//return getBoundedInt("What would you like to do? Choose 0 or 1 ",0,1);
		//out = (ComboItem) JOptionPane.showInputDialog("What would you like to do", JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION);
    	return JOptionPane.showOptionDialog(null,"Draw Random Or Pass?",
    			"Draw Card",JOptionPane.YES_NO_OPTION,
    			JOptionPane.QUESTION_MESSAGE,null,menuOptions,menuOptions[0]);
    }
    public void notifyFullHand(Player player){
    	JOptionPane.showMessageDialog(null, player.getName()+" your hand is full and you may not draw");
    }
    public void displayHand(Player player){
		Game7.displayText("------CURRENT HAND of "+player.getName()+"------");
    	for(int i = 0; i<player.handCount(); i++){
    		Game7.displayText(player.peekHand(i).toString());
    	}
    }
    public Integer discardHand(Player player){
    	displayHand(player);
    	//Game7.DisplayText("you may now discard any number of cards you wish");
    	ComboItem[] handContents = new ComboItem[player.handCount()];
    	for(int i = 0; i<player.handCount(); i++){
    		handContents[i]=new ComboItem(i,player.peekHand(i).toString());
    	}
    	ComboItem temp= ((ComboItem)JOptionPane.showInputDialog(null, "Please select any card you wish to discard", "Discard", JOptionPane.YES_OPTION, null, 
    			handContents, handContents[0]));
    	if(temp == null) return null;
    	else return temp.toInteger();
    }
    public Integer useHand(Player player){
    	//displayHand(player);
    	//Game7.DisplayText("you may now use your cards");
    	ComboItem[] handContents = new ComboItem[player.handCount()];
    	for(int i = 0; i<player.handCount(); i++){
    		handContents[i]=new ComboItem(i,player.peekHand(i).toString());
    	}
    	ComboItem temp= ((ComboItem)JOptionPane.showInputDialog(null, "Please select a card to use", "Play", JOptionPane.YES_OPTION, null, 
    			handContents, handContents[0]));
    	if(temp == null) return null;
    	else return temp.toInteger();
    }
    public void displayResources(Resource a){
    	Game7.displayText(a.toString());
    }
    public void spoilageA(Player player, Resource before, Resource after){
    	Game7.displayText(player.getName()+" Previous funds:");
    	displayResources(before);
    	Game7.displayText(player.getName()+" Current funds:");    	
    	displayResources(after);
    }
    public String drawProductionArea(Player player){
//    	String output=player.getName()+"\n   A   |   B   |   C   |   D   \n";
//    	for(int i = 0; i<4; i++){
//			output += i+"|";
//    		for(int j = 0; j<3; j++){
//    			output += player.getTerrain(i, j).toString();
//    			if(player.getTileType(i, j)!= null){
//    				output +=" "+player.getTileType(i, j).toString()+" | ";
//    			}else output += " -- | ";
//    		}
//    		output += player.getTerrain(i, 3);
//    		if(player.getTileType(i, 3)!= null){
//    			output +=" "+player.getTileType(i, 3).toString();
//    		}else output += " --";
//    		output +="\n----------------------------------------------------------------------------------\n";
//    }
//    	return output;
    	return detailedProdArea(player);	
    }
    public String detailedProdArea(Player player){
    	Board myBoard = player.getBoard();
    	String output="        ----A----       |       ----B----      |       ----C----      |       ----D----       \n";
    	for(int i = 0; i<4; i++){
			output += i+"|";
    		for(int j = 0; j<3; j++){
    			output+=myBoard.resourceArea[i][j].toString();
    			output+="|";
    		}
    		output +=" "+myBoard.resourceArea[i][3].toString();
    		output +="\n----------------------------------------------------------------------------------\n";
    	}
    	return output;
    }
    public void notifyEmptyHand(Player player){
    	JOptionPane.showMessageDialog(null, player.getName()+", it is recommended to have atleast 3 cards.");
    }
    public Tile explore(Player player, Tile[] tiles){
    	//ComboItem[] output = toCombo(tiles);
    	return (Tile) JOptionPane.showInputDialog(null, "Select a Tile", "card drawer", JOptionPane.YES_OPTION, null, tiles, tiles[0]);
    }
    public Integer getX(Player player, Tile tile){
    	Integer[] row = {0,1,2,3};
    	return ((Integer)JOptionPane.showInputDialog(null, "Select Row\n Current Tile: "+tile+"\n"+drawProductionArea(player), "coordinate", JOptionPane.YES_OPTION, null, row, row[0]));
    }
    public Integer getY(Player player, Tile tile){
    	Object[] column = {'A','B','C','D'};
    	ComboItem[] row = toCombo((Object[])column);
    	ComboItem temp = ((ComboItem)JOptionPane.showInputDialog(null, "Select Row\n Current Tile: "+tile+"\n"+drawProductionArea(player), "coordinate", JOptionPane.YES_OPTION, null, row, row[0]));
    	if(temp==null) return null;
    	else return temp.toInteger();
    }
    public Integer getX(Player player){
    	Integer[] row = {0,1,2,3};
    	return ((Integer)JOptionPane.showInputDialog(null, "Select Row\n"+drawProductionArea(player), "coordinate", JOptionPane.YES_OPTION, null, row, row[0]));
    }
    public Integer getY(Player player){
    	Object[] column = {'A','B','C','D'};
    	ComboItem[] row = toCombo((Object[])column);
    	return ((ComboItem)JOptionPane.showInputDialog(null, "Select Row\n"+drawProductionArea(player), "coordinate", JOptionPane.YES_OPTION, null, row, row[0])).toInteger();
    }
    
    private ComboItem[] toCombo(Object[] ary){
    	ComboItem[] out = new ComboItem[ary.length];
    	for(int i = 0; i < ary.length; i++){
    		out[i] = new ComboItem(i, ary[i].toString());
    	}
    	return out;
    }
    public boolean useGod(String card, String res){
    	ComboItem[] options = {new ComboItem(0,"Yes"),new ComboItem(1,"No")};
    	return JOptionPane.showOptionDialog(null,"Would you like to use God Powers?\n"
    			+"for "+res+"?","Use God Power",JOptionPane.YES_NO_OPTION,
    			JOptionPane.QUESTION_MESSAGE,null,options,options[1])==0;
    }
    
    public Integer tradeMenuPernament(Player player){
    	String[] menuOptions = {"2 Food","2 Wood","2 Favor","2 Gold","1 Food + 1 Wood", "1 Food + 1Favor",
    			"1 Food + 1 Gold", "1 Wood + 1 Favor", "1 Wood + 1 Gold", "1 Favor + 1 Gold"};
    	ComboItem[] items = new ComboItem[10];
    	for(int i = 0; i<10; i++){
    		items[i]=new ComboItem(i,menuOptions[i]);
    	}
    	ComboItem out=null;
    	while(out == null){
    		out = (ComboItem) JOptionPane.showInputDialog(null, "Choose to pay 2 resource cubes to continue", "Resource type option", JOptionPane.YES_OPTION, null, items, items[0]);
    		System.out.print(out);
    		System.out.println(out.toInt());
    	}
    	return out.toInt();
    }
    public Integer tradeMenuRandom(Player player){
    	String[] menuOptions = {"1 Food","1 Wood","1 Favor","1 Gold"};
    	ComboItem[] items = new ComboItem[4];
    	for(int i = 0; i<4; i++){
    		items[i]=new ComboItem(i,menuOptions[i]);
    	}
    	ComboItem out=null;
    	while(out == null){
    		out = (ComboItem) JOptionPane.showInputDialog(null, "Choose to pay 1 resource cube to continue", "Resource type option", JOptionPane.YES_OPTION, null, items, items[0]);
    		System.out.print(out);
    		System.out.println(out.toInt());
    	}
    	return out.toInt();
    }
    public Integer buildMenu(){
    	String[] menuOptions = {"Wall","Tower","Storehouse","Market","Armory","Quarry","Monument","Granary","Gold Mint",
    							"Wood Workshop","Siege Engine Workshop","Great Temple","The Wonder","House"}; 
    	ComboItem[] items = new ComboItem[14];
    	for(int i = 0; i<14; i++){
    		items[i]=new ComboItem(i,menuOptions[i]);
    	}
    	ComboItem out=null;
    	while(out == null){
    		out = (ComboItem) JOptionPane.showInputDialog(null, "Pick building you want to build", "Building", JOptionPane.YES_OPTION, null, items, items[0]);
    		System.out.print(out);
    		System.out.println(out.toInt());
    	}
    	return out.toInt();
    }

    public boolean gatherType(Player player){
    	ComboItem[] options = {new ComboItem(0,"Resource Type"),new ComboItem(1,"Terrain Type")};
    	return JOptionPane.showOptionDialog(null,player.getName()+"\nGather By Resource Type or Terrain Type",
    			"Choose Gather Method",JOptionPane.YES_NO_OPTION,
    			JOptionPane.QUESTION_MESSAGE,null,options,options[0])==0;
    }
    public void moveVillager(Player player){
    	ComboItem[] options = {new ComboItem(0,"Place"),new ComboItem(1,"Remove"), new ComboItem(2,"Done")};
    	boolean done = false;
    	while(!done){
	    	int out =  JOptionPane.showOptionDialog(null,"Move Villagers","Move Villagers",JOptionPane.YES_NO_CANCEL_OPTION,
	    		JOptionPane.QUESTION_MESSAGE,null,options,options[2]);
	    	Integer x;
	    	Integer y;
	    	switch(out){
	    	case 0: //place villagers
	    		x = getX(player);
	    		y = getY(player);
	    		if(x==null || y == null){
	    			break;
	    		}else{
	    			if(player.getVillagerCnt()>0 && player.getTileType(x, y)!=null && !player.getBoard()
	    			.resourceArea[x][y].hasVillager()){
	    				
	    				
	    				player.getBoard().resourceArea[x][y].attachVillager();
	    				player.decVillager();
	    			}
	    			else Game7.displayText("Cannot Place Villager");
	    		}
	    		break;
	    	case 1: //remove villagers
	    		x = getX(player);
	    		y = getY(player);
	    		if(x==null || y == null){
	    			break;
	    		}else{
	    			if(player.getVillagerCnt()>0 && player.getTileType(x, y)!=null && player.getBoard()
	    	    			.resourceArea[x][y].hasVillager()){
	    				
	    				player.getBoard().resourceArea[x][y].removeVillager();
	    				player.incVillager();
	    			}
	    			else Game7.displayText("Cannot Remove Villager");
	    		}
	    		break;
	    		
	    	case 2: //done
	    		done = true;
	    		break;
	    	}
    	}
    }
    public Terrain selectTerrain(Player player){
    	Terrain[] ter = Terrain.values();
    	return (Terrain) JOptionPane.showInputDialog(null, "Select Terrain "+player.getName(), "Terrain selecter", JOptionPane.YES_OPTION, null, ter, ter[0]);
    }
    public Resources selectResource(Player player){
    	Resources[] res = Resources.values();
    	return (Resources) JOptionPane.showInputDialog(null, "Select Resource Type "+player.getName(), "Resource chooser", JOptionPane.YES_OPTION, null, res, res[0]);
    }
    public String drawPlayer(Player player){
    	String out ="";
    	out +="        Player: "+player.getName()+"     "+"Your age:"+player.getAge()+"\n";
    	out +="Your buildings: ";
    	out +=player.getBoard().buildings.toString()+"\n";
    	out +="Your resources: ";
    	out +=player.getWallet().getFunds().toString();
    	out +="\nYour hand: \n";
    	for(int i = 0; i<player.handCount(); i++){
    		out +=(player.peekHand(i).toString())+"\n";
    	}
    	out +="Resource Area: \n";
    	out +=detailedProdArea(player);
    	return out;
    }
}//end class UI
